﻿package {
	import flash.display.*;
	import flash.text.*;
	import flash.events.*;
	import flash.net.*;
	import flash.ui.*;
	public class CenFunClock extends Sprite {
		private var lgs:Array;
		private var lg:int;
		private var sw:Number;
		private var sh:Number;
		private var sm:Number;
		//
		private var cookie:SharedObject;
		private var clock:Object;
		//
		private var colorFinger:Number = 0x008000;
		private var colorBorder:Number = 0x999999;
		private var colorFont:Number = 0x333333;
		private var gear:Number = 3;
		private var space:Number = 2;
		private var border:Number = 1;
		//
		private var years:Sprite;
		private var months:Sprite;
		private var days:Sprite;
		private var hours:Sprite;
		private var minutes:Sprite;
		private var seconds:Sprite;
		private var finger:Sprite;
		//
		private var date:Date;
		public function CenFunClock():void {
			stage.align = "TL";
			stage.scaleMode = "noScale";
			//
			cookie = SharedObject.getLocal("cenfun_com_clock_local_data");
			clock = {year:{value:null,width:200,height:18,size:11,offset:0},month:{value:null,width:150,height:18,size:11,offset:0},day:{value:null,width:100,height:18,size:11,offset:0},hour:{value:null,width:50,height:18,size:11,offset:0},minute:{value:null,width:30,height:18,size:11,offset:0},second:{value:null,width:10,height:18,size:11,offset:0}};
			//
			lgs = [];
			lgs.push([11, ["January","February","March","April","May","June","July","August","September","October","November","December"],["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]]);
			lgs.push([12, ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],["星期日","星期一","星期二","星期三","星期四","星期五","星期六"]]);
			lgs.push([11, ["JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"],["SUN","MON","TUE","WED","THU","FRI","SAT"]]);
			//
			lg = parseInt(getCookie("lg"));
			if (isNaN(lg)) {
				lg = 0;
			}
			//
			years = new Sprite();
			months = new Sprite();
			days = new Sprite();
			hours = new Sprite();
			minutes = new Sprite();
			seconds = new Sprite();
			finger = new Sprite();
			//
			addChild(years);
			addChild(months);
			addChild(days);
			addChild(hours);
			addChild(minutes);
			addChild(seconds);
			addChild(finger);
			//
			resizeHandler();
			this.addEventListener(Event.ADDED_TO_STAGE, stageHandler);
			//
			var m:ContextMenu = new ContextMenu();
			m.hideBuiltInItems();
			var t:ContextMenuItem = new ContextMenuItem("CenFun Clock");
			t.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, openPage);
			m.customItems.push(t);
			this.contextMenu = m;
		}
		private function openPage(e:ContextMenuEvent):void {
			try {
				flash.net.navigateToURL(new URLRequest("http://www.cenfun.com"), "_blank");
			} catch (e:Error) {
			}
		}
		private function stageHandler(e:Event):void {
			stage.addEventListener(MouseEvent.CLICK,clickHandler);
			stage.addEventListener(Event.RESIZE,resizeHandler);
			stage.addEventListener(Event.ENTER_FRAME,clockHandler);
		}
		private function resizeHandler(e:Event=null):void {
			sw = stage.stageWidth;
			sh = stage.stageHeight;
			sm = Math.round(sh * 0.5);
			//
			drawFinger();
			//
			clock.year.value = null;
			clock.month.value = null;
			clock.day.value = null;
			clock.hour.value = null;
			clock.minute.value = null;
			clock.second.value = null;
			//
			clockHandler();
		}
		private function clockHandler(e:Event=null):void {
			date = new Date  ;
			//
			drawSeconds();
			drawMinutes();
			drawHours();
			drawDays();
			drawMonths();
			drawYears();
		}
		//==========================================================================
		private function drawSeconds():void {
			var this_second:Number = date.seconds;
			var per_second:Number = date.milliseconds * 0.001;
			if (clock.second.value == null) {
				clock.second.value = this_second;
				clearChildren(seconds);
				//
				var num:Number = Math.ceil(sw / clock.second.width);
				if (num < 60) {
					num = 60;
				}
				var total:Number = num * 3;
				drawDial(seconds,clock.second,total);
				//
				clock.second.offset = sw * 0.5 - num * clock.second.width;
				for (var i:uint = 0; i < total; i++) {
					var the_second:Number = i - num;
					if (the_second % 5 == 0) {
						the_second = the_second % 60;
						if (the_second < 0) {
							the_second = the_second + 60;
						}
						var str:String = the_second.toString();
						var tag:TextField = getTag(str,clock.second.size);
						tag.x = clock.second.width * i - tag.width * 0.5;
						tag.y = clock.second.height * 0.5 - tag.height * 0.5;
						seconds.addChild(tag);
					}
				}
				seconds.y = sm + space * 0.5 + clock.hour.height + space + clock.minute.height + space;
			}
			seconds.x = clock.second.offset - (this_second + per_second) * clock.second.width;
		}
		//==========================================================================
		private function drawMinutes():void {
			var this_minute:Number = date.minutes;
			var per_minute:Number = date.seconds / 60;
			if (clock.minute.value == null) {
				clock.minute.value = this_minute;
				clearChildren(minutes);
				//
				var num:Number = Math.ceil(sw / clock.minute.width);
				if (num < 60) {
					num = 60;
				}
				var total:Number = num * 3;
				drawDial(minutes,clock.minute,total);
				//
				clock.minute.offset = sw * 0.5 - num * clock.minute.width;
				for (var i:uint = 0; i < total; i++) {
					var the_minute:Number = i - num;
					the_minute = the_minute % 60;
					if (the_minute < 0) {
						the_minute = the_minute + 60;
					}
					var str:String = the_minute.toString();
					var tag:TextField = getTag(str,clock.minute.size);
					tag.x = clock.minute.width * i - tag.width * 0.5;
					tag.y = clock.minute.height * 0.5 - tag.height * 0.5;
					minutes.addChild(tag);
				}
				minutes.y = sm + space * 0.5 + clock.hour.height + space;
			}
			minutes.x = clock.minute.offset - (this_minute + per_minute) * clock.minute.width;
		}
		//==========================================================================
		private function drawHours():void {
			var this_hour:Number = date.hours;
			var per_hour:Number = date.minutes / 60;
			if (clock.hour.value == null) {
				clock.hour.value = this_hour;
				clearChildren(hours);
				//
				var num:Number = Math.ceil(sw / clock.hour.width);
				if (num < 24) {
					num = 24;
				}
				var total:Number = num * 3;
				drawDial(hours,clock.hour,total);
				//
				clock.hour.offset = sw * 0.5 - num * clock.hour.width;
				for (var i:uint = 0; i < total; i++) {
					var the_hour:Number = i - num;
					the_hour = the_hour % 24;
					if (the_hour < 0) {
						the_hour = the_hour + 24;
					}
					var str:String = the_hour.toString();
					var tag:TextField = getTag(str,clock.hour.size);
					tag.x = clock.hour.width * i - tag.width * 0.5;
					tag.y = clock.hour.height * 0.5 - tag.height * 0.5;
					hours.addChild(tag);
				}
				hours.y = sm + space * 0.5;
			}
			hours.x = clock.hour.offset - (this_hour + per_hour) * clock.hour.width;
		}
		//==========================================================================
		private function drawDays():void {
			var this_day:Number = date.date;
			var per_day:Number = (date.hours + date.minutes / 60) / 24;
			if (clock.day.value != this_day) {
				clock.day.value = this_day;
				clearChildren(days);
				//
				var num:Number = Math.ceil(sw / clock.day.width);
				if (num < 2) {
					num = 2;
				}
				var total:Number = num * 3;
				drawBorder(days,clock.day,total);
				//
				clock.day.offset = sw * 0.5 - num * clock.day.width;
				//
				var size:Number = lgs[lg][0];
				for (var i:uint = 0; i < total; i++) {
					var gmt1970:Number = date.time + (i - num) * 1000 * 60 * 60 * 24;
					var the_date:Date = new Date(gmt1970);
					var the_day:Number = the_date.date;
					var the_week:Number = the_date.day;
					var str:String = "<b>" + the_day + "</b> " + lgs[lg][2][the_week];
					if (the_week == 0) {
						str = "<font color='#ff0000'>" + str + "</font>";
					} else if (the_week == 6) {
						str = "<font color='#008000'>" + str + "</font>";
					}
					var tag:TextField = getTag(str,size);
					tag.x = clock.day.width * i + clock.day.width * 0.5 - tag.width * 0.5;
					tag.y = clock.day.height * 0.5 - tag.height * 0.5;
					days.addChild(tag);
				}
				days.y = sm - space * 0.5 - clock.day.height;
			}
			days.x = clock.day.offset - per_day * clock.day.width;
		}
		//==========================================================================
		private function drawMonths():void {
			var this_month:Number = date.month;
			var per_month:Number = (date.date - 1 + date.hours / 24) / getdays(date.fullYear, this_month + 1);
			if (clock.month.value == null) {
				clock.month.value = this_month;
				clearChildren(months);
				//
				var num:Number = Math.ceil(sw / clock.month.width);
				if (num < 12) {
					num = 12;
				}
				var total:Number = num * 3;
				drawBorder(months,clock.month,total);
				//
				clock.month.offset = sw * 0.5 - num * clock.month.width;
				//
				var size:Number = lgs[lg][0];
				for (var i:uint = 0; i < total; i++) {
					var the_month:Number = i - num;
					the_month = the_month % 12;
					if (the_month < 0) {
						the_month = the_month + 12;
					}
					var str:String = lgs[lg][1][the_month];
					var tag:TextField = getTag(str,size);
					tag.x = clock.month.width * i + clock.month.width * 0.5 - tag.width * 0.5;
					tag.y = clock.month.height * 0.5 - tag.height * 0.5;
					months.addChild(tag);
				}
				months.y = sm - space * 0.5 - clock.day.height - space - clock.month.height;
			}
			months.x = clock.month.offset - (this_month + per_month) * clock.month.width;
		}
		//==========================================================================
		private function drawYears():void {
			var this_year:Number = date.fullYear;
			var per_year:Number = (date.month + (date.date - 1) / getdays(this_year, date.month + 1)) / 12;
			if (clock.year.value != this_year) {
				clock.year.value = this_year;
				clearChildren(years);
				//
				var num:Number = Math.ceil(sw / clock.year.width);
				if (num < 2) {
					num = 2;
				}
				var total:Number = num * 3;
				drawBorder(years,clock.year,total);
				//
				clock.year.offset = sw * 0.5 - num * clock.year.width;
				//
				for (var i:uint = 0; i < total; i++) {
					var the_year:Number = i - num + this_year;
					var str:String = the_year.toString();
					var tag:TextField = getTag(str,clock.year.size);
					tag.x = clock.year.width * i + clock.year.width * 0.5 - tag.width * 0.5;
					tag.y = clock.year.height * 0.5 - tag.height * 0.5;
					years.addChild(tag);
				}
				years.y = sm - space * 0.5 - clock.day.height - space - clock.month.height - space - clock.year.height;
			}
			years.x = clock.year.offset - per_year * clock.year.width;
		}
		//=======================================================================================
		private function drawFinger():void {
			finger.graphics.clear();
			finger.graphics.lineStyle(border,colorFinger,0.5,true);
			finger.graphics.moveTo(sw * 0.5,sm - space * 0.5 - clock.day.height - space - clock.month.height - space - clock.year.height);
			finger.graphics.lineTo(sw * 0.5,sm + space * 0.5 + clock.hour.height + space + clock.minute.height + space + clock.second.height);
		}
		private function getdays(this_year:Number, this_month:Number):Number {
			var days;
			if (this_month == 2) {
				if ((this_year%100 != 0 && this_year%4 == 0) || this_year%400 == 0) {
					days = 29;
				} else {
					days = 28;
				}
			} else if (this_month == 4 || this_month == 6 || this_month == 9 || this_month == 11) {
				days = 30;
			} else {
				days = 31;
			}
			return days;
		}
		//
		private function drawBorder(sp:Sprite,config:Object,num:Number):void {
			sp.graphics.clear();
			sp.graphics.lineStyle(border,colorBorder,1,true);
			for (var i:uint = 0; i < num; i++) {
				sp.graphics.drawRect(i * config.width,0,config.width,config.height);
			}
		}
		private function drawDial(sp:Sprite,config:Object,num:Number):void {
			sp.graphics.clear();
			sp.graphics.lineStyle(border,colorBorder,1,true);
			for (var i:uint = 0; i < num; i++) {
				var spx:Number = i * config.width;
				sp.graphics.moveTo(spx,gear);
				sp.graphics.lineTo(spx,0);
				sp.graphics.lineTo(spx + config.width,0);
				sp.graphics.lineTo(spx + config.width,gear);
				sp.graphics.moveTo(spx,config.height - gear);
				sp.graphics.lineTo(spx,config.height);
				sp.graphics.lineTo(spx + config.width,config.height);
				sp.graphics.lineTo(spx + config.width,config.height - gear);
			}
		}
		//
		private function clickHandler(e:Event):void {
			lg++;
			if (lg >= lgs.length) {
				lg = 0;
			}
			setCookie("lg", lg);
			clock.month.value = null;
			clock.day.value = null;
		}

		//=====================================================================================

		private function getTag(tt:String,size:Number=12):TextField {
			var tag:TextField = new TextField();
			tag.selectable = false;
			tag.mouseEnabled = false;
			tag.tabEnabled = false;
			tag.autoSize = "left";
			tag.defaultTextFormat = new TextFormat("Arial",size,colorFont);
			tag.htmlText = tt;
			//trace(tt)
			return tag;
		}
		private function clearChildren(sp:Sprite):void {
			while (sp.numChildren) {
				sp.removeChildAt(0);
			}
		}
		//Cookies-----------------------------------------------
		private function getCookie(n:String):String {
			return cookie.data[n];
		}
		private function setCookie(n:String,v:Object):void {
			cookie.data[n] = v.toString();
		}

	}
}